Used to prevent modification:
final int x = 10; // cannot change x again final class Vehicle { } // cannot be extended class A { final void show() { System.out.println("Final method"); } }
x = 20; // β Error: cannot assign a value to final variable
class MyClass { static int count = 0; // shared across all objects static void display() { System.out.println("Static method"); } } MyClass.display(); // No object needed
A class is like a blueprint, and an instance is a real object created from that
class.
For example:
Student s1 = new Student(); β s1 is an instance of the Student class.
class Student { int roll; // instance variable Student(int roll) { this.roll = roll; // this.roll = instance variable, roll = local variable } void show() { System.out.println("Roll number: " + this.roll); } } public class Main { public static void main(String[] args) { Student s1 = new Student(101); s1.show(); // Output: Roll number: 101 } }
class Book { String title; int price; // No-argument constructor Book() { this("Java", 500); // calls another constructor } Book(String title, int price) { this.title = title; this.price = price; } void show() { System.out.println(title + " - Rs." + price); } }
class Person { void print(Person p) { System.out.println("This is: " + p); } void call() { print(this); // passes current object to print() } }
class Animal { String name = "Animal"; void speak() { System.out.println("Animal speaks"); } } class Dog extends Animal { String name = "Dog"; void printNames() { System.out.println(super.name); // Animal System.out.println(this.name); // Dog } void speak() { super.speak(); // Call parent method System.out.println("Dog barks"); } }
Imagine two workers (threads) checking a note (variable). If one keeps a copy in his pocket and the
other updates the note on the wall, the first wonβt see the change.
With volatile: The worker must always check the wall, not his pocket.
class SharedResource { volatile boolean running = true; void stop() { running = false; } void work() { while (running) { // do some work } System.out.println("Thread stopped."); } }
If asked βWhat does volatile do?β say:
βIt guarantees visibility of changes to variables across threads β all threads see the most
recent value.β
Serialization is the process of converting an object into a byte stream so it can be saved to a file or sent over a network.
Deserialization is converting that byte stream back into the original object.
Imagine youβre saving a User object to a file. You want to save the name but not the password. So, you mark the password field as transient to hide it.
import java.io.*; class User implements Serializable { String name; transient String password; User(String name, String password) { this.name = name; this.password = password; } } public class Main { public static void main(String[] args) throws Exception { User user1 = new User("Deepak", "secret123"); // Serialize FileOutputStream fos = new FileOutputStream("user.txt"); ObjectOutputStream oos = new ObjectOutputStream(fos); oos.writeObject(user1); oos.close(); // Deserialize FileInputStream fis = new FileInputStream("user.txt"); ObjectInputStream ois = new ObjectInputStream(fis); User savedUser = (User) ois.readObject(); ois.close(); System.out.println("Name: " + savedUser.name); // Output: Deepak System.out.println("Password: " + savedUser.password); // Output: null } }
Q: What does transient do in Java?
A: It tells the JVM to skip this variable when serializing an object.
Think of a toilet in a public restroom. Only one person can go in at a time (it has a lock). The
others must wait.
synchronized acts like that lock in your code.
class Counter { private int count = 0; // synchronized method ensures one thread at a time synchronized void increment() { count++; } int getCount() { return count; } }
// 1. Synchronized Method synchronized void methodA() { // critical code } // 2. Synchronized Block void methodB() { synchronized(this) { // critical code } }
Q: Why is synchronized important?
A: It prevents race conditions by allowing only one thread to access critical code
at a time.
Imagine you have a list of animals. You want to perform dog tricks, but only if the animal is a dog. So you check: "Is this animal a Dog?" β Thatβs what instanceof does.
class Animal {} class Dog extends Animal {} class Cat extends Animal {} public class Test { public static void main(String[] args) { Animal a = new Dog(); // a is of type Animal, but actually refers to a Dog if (a instanceof Dog) { System.out.println("It's a Dog!"); } if (a instanceof Cat) { System.out.println("It's a Cat!"); } else { System.out.println("It's NOT a Cat"); } } } // Output: // It's a Dog! // It's NOT a Cat
class Animal {} class Dog extends Animal { void bark() { System.out.println("Woof!"); } } public class Main { public static void main(String[] args) { Animal a = new Dog(); if (a instanceof Dog) { Dog d = (Dog) a; // Safe casting d.bark(); // Woof! } } }
Q: Why is instanceof used in Java?
A: It checks whether an object is of a specific class type to safely perform
downcasting and avoid runtime errors.
Keyword | Purpose | Common Use Case |
---|---|---|
final | Prevent change | Constants, prevent method override |
static | Shared by all objects | Utility methods, shared counters |
this | Refers to current object | Resolve variable name conflict |
super | Refers to parent class | Inheritance, call parent constructor |
volatile | Thread-safe visibility | Flags in multi-threading |
transient | Skip during serialization | Hide sensitive data |
synchronized | Thread-safe method/block | Avoid race condition |
instanceof | Check object type before casting | Polymorphism, type safety |